<?php


namespace XiaoGuai\DataStructure\LineList\SqLine;

use XiaoGuai\DataStructure\LineList\ListInterface;

/**
 * 线性表的顺序存储表示
 * Class SqLine
 * @package XiaoGuai\DataStructure\LineList\SqLine
 */
class SqLine implements ListInterface
{
    /**
     * 线性表的最大长度100
     */
    const MAX_SIZE = 100;

    /**
     * @var array 存放数据元素
     */
    protected $elements = [];

    /**
     * @var int 链表的长度
     */
    protected $length = 0;

    /**
     * 顺序存储线性表的初始化,构造一个线性表
     * SqLine constructor.
     */
    public function __construct()
    {
        $this->elements = [];
        $this->length = 0;
    }

    /**
     * 根据索引获取元素
     * 之间返回数据数组的对应位置的值
     * @param int $index
     * @return mixed
     * @throws \Exception
     */
    public function getElement(int $index)
    {
        if ($index < 0 || $index >= $this->length) {
            throw new \Exception('overflow');
        }
        return $this->elements[$index];
    }

    public function getLength(): int
    {
        return $this->length;
    }

    /**
     * 查找元素的索引
     * 依次扫描数据数组每个元素,对比元素数值,返回索引
     * @param $element
     * @return int
     */
    public function getIndex($element): int
    {
        for ($i = 0; $i < $this->length; $i++) {
            if ($this->elements[$i] == $element) {
                return $i;
            }
        }
        return -1;
    }

    /**
     * 在对应索引处前面插入数据元素
     * 在数据数组对应索引位置依次后移后面的每个元素,然后再插入
     * @param $index
     * @param $element
     * @return bool
     */
    public function insertElement(int $index, $element): bool
    {
        if ($index < 0 || $index > $this->length || $this->length == self::MAX_SIZE) {
            return false;
        }

        for ($i = $this->length; $i > $index; $i--) {
            $this->elements[$i] = $this->elements[$i - 1];
        }
        $this->elements[$i] = $element;
        $this->length++;
        return true;
    }

    /**
     * 删除对应索引位置的元素
     * 在数据数组对应索引位置依次前移后面的每个元素
     * @param int $index
     * @return bool
     */
    public function deleteElement(int $index): bool
    {
        if ($index < 0 || $index >= $this->length) {
            return false;
        }

        for ($i = $this->length - 1; $i > $index; $i--) {
            $this->elements[$i - 1] = $this->elements[$i];
        }
        $this->length--;
        return true;
    }

    /**
     * 判断线性表是否为空
     * @return bool
     */
    public function isEmpty(): bool
    {
        return $this->length == 0 ? true : false;
    }

    /**
     * 清空线性表,将线性表的数据初始化
     */
    public function clear()
    {
        $this->elements = [];
        $this->length = 0;
    }
}